﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NetfractionHub.Network.Protocol.BASE.Handler
{
    public class HandlerCTM : ProtocolMessageActionHandler
    {
        public HandlerCTM()
            : base()
        {
            mSupportedConnectionStates = new List<RemoteMachine.ConnectionState>();
        }

        #region ProtocolMessageActionHandler Members

        public override string ProtocolActionCode
        {
            get { return "CTM"; }
        }

        public override bool HandleProtocolMessage(RemoteMachine.Node node, ProtocolMessage message, IEnumerable<ProtocolFeature> extenders)
        {
            if (!(node is RemoteMachine.Client))
                return false;

            if (!(message.Parameters.Count == 3 && message.MessageType == ProtocolMessage.MessageTypeEnum.Direct))
                return false;

            if (!Security.Permission.HasPermission(node.SecurityIdentity, typeof(Security.Permissions.DownloadPermission)))
            {
                LocalMachine.SecurityBot.GetInstance().SendEchoMessageFromBot(node, Security.Permission.GetDeniedString(typeof(Security.Permissions.DownloadPermission)));
                return false;
            }

            RemoteMachine.Node targetNode = ConnectionManager.GetNodeBySessionId(message.TargetSessionId);

            if (targetNode == null)
                return false;   // send STA: session ID doesn't exist

            if (!Security.Permission.HasPermission(targetNode.SecurityIdentity, typeof(Security.Permissions.SharePermission)))
            {
                LocalMachine.SecurityBot.GetInstance().SendEchoMessageFromBot(node, Security.Permission.GetDeniedString(typeof(Security.Permissions.SharePermission)));
                return false;
            }

            string protocol = message.Parameters[0].ParameterValue;
            string port = message.Parameters[1].ParameterValue;
            string token = message.Parameters[2].ParameterValue;

            if (!((targetNode.Identity.NodeType & IdentityNodeTypes.Bot) == IdentityNodeTypes.Bot | (targetNode.Identity.NodeType & IdentityNodeTypes.Hub) == IdentityNodeTypes.Hub))
            {
                if (message.Parameters[0].ParameterValue == "ADC/0.10")
                    message.Parameters[0].ParameterValue = "ADC/1.0";

                ConnectionManager.SendPeerConnectRequest(message);
                // this is a hack to support jUCy!
                
                // this probably should be the client's business, not the hub's.
                //if (protocol == "ADC/1.0" || protocol == "ADC/0.10")
                //{
                //    //ConnectionManager.SendPeerConnectRequest(message);
                //}
                //else
                //{
                //    /*  ProtocolMessageFactory factory = new Factory.FactorySTA();
                //        Dictionary<int, object> factoryParams = new Dictionary<int, object>();
                //        factoryParams.Add((int)Factory.FactorySTA.ParameterEnum.SessionID, node.SessionId);
                //        factoryParams.Add((int)Factory.FactorySTA.ParameterEnum.InitiatorSID, message.SessionId);
                //        factoryParams.Add((int)Factory.FactorySTA.ParameterEnum.Severity, Factory.FactorySTA.StatusSeverity.FatalError);
                //        factoryParams.Add((int)Factory.FactorySTA.ParameterEnum.Code, Factory.FactorySTA.StatusErrorCode.TransferProtocolUnsupported);
                //        factoryParams.Add((int)Factory.FactorySTA.ParameterEnum.Token, token);
                //        factoryParams.Add((int)Factory.FactorySTA.ParameterEnum.Protocol, protocol);
                //        node.Connection.Send(factory.Create(ProtocolMessage.MessageTypeEnum.Direct, factoryParams).ToString());*/
                //}
            }
            else
            {
                // send STA.. Hub and Bot's dont do CTM, though technically Hub could.
                Console.WriteLine("Cannot send CTM to: {0}", targetNode.Identity.Nickname);
            }
            return true;
        }

        #endregion
    }
}
